package com.dhp.mq;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dhp.Utils.AIUtil;
import com.dhp.Utils.RetryUtil;
import com.dhp.Utils.WebSocketUtil;
import com.dhp.common.ErrorCode;
import com.dhp.constant.GenChartConstant;
import com.dhp.constant.MQConstant;
import com.dhp.constant.UserConstant;
import com.dhp.exception.BusinessException;
import com.dhp.model.entity.Chart;
import com.dhp.model.entity.ChartData;
import com.dhp.model.enums.GenChartStatusEnum;
import com.dhp.service.ChartDataService;
import com.dhp.service.ChartService;
import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

@Component
@Slf4j
public class MyMessageConsumer {

    @Resource
    private AIUtil aiUtil;

    @Resource
    private ChartService chartService;

    @Autowired
    private ChartDataService chartDataService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RetryUtil retryUtil;

    @Autowired
    private WebSocketUtil webSocketUtil;

    @RabbitListener(queues = {MQConstant.QUEUE_NAME} , ackMode = "MANUAL")
    public void receiveMessage(String message , Channel channel , @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag){

        try {
            //message为空则拒绝消息
            if(StrUtil.isEmpty(message)){
                channel.basicNack(deliveryTag , false , false);
            }
        }catch (IOException e) {
            throw new RuntimeException(e);
        }


            //执行业务
            //将数据存储到数据库 将状态修改为执行中
            Long chartId = Long.parseLong(message);
            Chart chart = new Chart();
            chart.setId(chartId);
            chart.setStatus(GenChartStatusEnum.RUNNING.getValue());
            chartService.updateById(chart);


            //获取AI完整的回答
            Chart RunningChart = chartService.getById(chartId);

            //根据charId查询data
            QueryWrapper<ChartData> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("chartId" , RunningChart.getId());
            ChartData data = chartDataService.getOne(queryWrapper);
            if (data == null){
                try {
                    channel.basicAck(deliveryTag , false);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                throw new BusinessException(ErrorCode.OPERATION_ERROR , "分析失败");
            }

            String userRequest = chartService.getUserInput(RunningChart , data);
            String fullAns = aiUtil.doChat(userRequest);


            if (StringUtils.isEmpty(fullAns)){
                try {
                    channel.basicAck(deliveryTag , false);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                throw new BusinessException(ErrorCode.OPERATION_ERROR , "分析失败");
            }

            //将回答拆分
            String[] split = fullAns.split(GenChartConstant.AI_CHART_SPILT);

        //判断生成的答案是否符合预期 执行retry
        if (split.length < 3){
            try {
                webSocketUtil.sendOneMessage(RunningChart.getUserId().toString() , "系统出错，正在重试");
                String ans = retryUtil.retryChart(userRequest);
                String[] sp = ans.split(GenChartConstant.AI_CHART_SPILT);
                work(RunningChart , sp[1] , sp[2] , deliveryTag , channel);
            }catch (Exception e){
                e.printStackTrace();
            }
        }else {
            work(RunningChart, split[1], split[2], deliveryTag, channel);
        }
    }

    public void work(Chart RunningChart , String genChart , String genResult , long deliveryTag , Channel channel){
        //将数据存储到数据库
        Chart finalChart = new Chart();
        if (!StrUtil.isAllNotEmpty(genChart , genResult)){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        BeanUtil.copyProperties(RunningChart , finalChart);
        finalChart.setId(RunningChart.getId());
        finalChart.setGenChart(genChart);
        finalChart.setGenResult(genResult);
        finalChart.setStatus(GenChartStatusEnum.SUCCEED.getValue());
        chartService.updateById(finalChart);
        webSocketUtil.sendOneMessage(finalChart.getUserId().toString() , "图表生成好啦，快去看看吧！");


        //更新redis
        Gson gson = new Gson();
        String key = UserConstant.CHART_KEY_PRE + finalChart.getUserId();
        QueryWrapper<Chart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId" , RunningChart.getUserId());
        List<Chart> list = chartService.list(queryWrapper);
        String JsonStr = gson.toJson(list);
        redisTemplate.opsForValue().set(key , JsonStr);

        try {
            channel.basicAck(deliveryTag , false);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
